package com.roc.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.directwebremoting.json.types.JsonArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.roc.dao.DaoException;
import com.roc.dao.IBaseDao;
import com.roc.dao.ISQLBaseDao;
import com.roc.pojo.AuditingItem;
import com.roc.pojo.MessageSend;
import com.roc.pojo.OperatorAuth;
import com.roc.pojo.OperatorReceive;
import com.roc.pojo.Operators;
import com.roc.service.IMerchantServices;
import com.roc.service.ServiceException;
import com.roc.service.operator.OperatorReceiveService;
import com.roc.util.constant.AuditingResultCodeType;
import com.roc.util.constant.AuditingType;
import com.roc.util.constant.SysLogType;

@Service
@Transactional(rollbackFor = { ServiceException.class })
public class OperatorReceiveServiceImpl implements OperatorReceiveService {
	
	private Logger logger=LogManager.getLogger(OperatorReceiveServiceImpl.class);
	
	private boolean verifyInfo;
	@Autowired
	ISQLBaseDao sqlBaseDao;
	
	@Autowired
	private IBaseDao baseDao;
	@Autowired
	IMerchantServices merinfoService;
	

	@Override
	public List<String> addReceiveInfo(Operators op, String accountIdList)
			throws ServiceException {
		String sql = " select count(*) from T_DYPAY_OPERATORS_RECEIVE t where t.status!='1' and t.operator_auth_id=?";
		String updateSql = "update t_dypay_operators_detail t set t.status='3' where t.id=?";
		Object[] params =  new Object[1];
		List<String> receiveList = new ArrayList<String>();
		try{
			String[] accountNoArray = accountIdList.split(",");
			int count = 0;
			for(int i = 0;i<accountNoArray.length;i++){
				params[0] = accountNoArray[i];
				List<Object> objParmas = new ArrayList<Object>();
				objParmas.add(accountNoArray[i]);
				Object obj = sqlBaseDao.findObj(sql, params);
				count = Integer.parseInt(obj.toString());
				if(count>0){
					receiveList.add(accountNoArray[i]);
					continue;
				}else{
					OperatorAuth operatorAuth = (OperatorAuth)baseDao.loadById(Long.parseLong(accountNoArray[i]), OperatorAuth.class);
					OperatorReceive operatorReceive = new OperatorReceive();
					operatorReceive.setAccountNo(operatorAuth.getAccountNo());
					operatorReceive.setOperatorAuthId(Long.parseLong(accountNoArray[i]));
					operatorReceive.setOpAccountNo(op.getAccountNo());
					operatorReceive.setOpAccountName(op.getRealName());
					operatorReceive.setOpId(op.getId());
					operatorReceive.setCreateAt(new Date());
					operatorReceive.setCreateBy(op.getAccountNo());
					operatorReceive.setStatus(OperatorReceive.STATUS_ONE);
					baseDao.editSave(operatorReceive);
					sqlBaseDao.deleteBySql(updateSql, objParmas);
				}
			}
		}catch(Exception e){
			logger.error(e.getMessage(),e);
			throw new ServiceException(e.getMessage(),e);
		}
		
		return receiveList;
	}

	@Override
	public String updateReceiveInfo(Operators op, Long receiveId,String status,String resultDetail)
			throws ServiceException {
		OperatorAuth operatorAuth = new OperatorAuth();
		OperatorReceive operatorReceive = new OperatorReceive();
		List<Object> objList = new ArrayList<Object>();
		StringBuffer updateSqlOp = new StringBuffer();
		try{
			operatorReceive = (OperatorReceive)baseDao.loadById(receiveId, OperatorReceive.class);
			operatorAuth = (OperatorAuth)baseDao.loadById(operatorReceive.getOperatorAuthId(), OperatorAuth.class);
			String querySql = "select count(1) from t_operators where card_no=? and status!='02' and ACCOUNT_NO!=? and ROLE_TYPE='17'";
			Object[] params =  new Object[2];
			params[0] = operatorAuth.getCardNo();
			params[1] = operatorAuth.getAccountNo();
			Object obj = sqlBaseDao.findObj(querySql, params);
			int count = Integer.parseInt(obj.toString());
				StringBuffer sb = new StringBuffer();
				if(AuditingResultCodeType.PASS.getCode().equals(status)){
					if(count<2){
						//身份证二要素验证
						HttpServletResponse response=ServletActionContext.getResponse();
						response.setContentType("text/json;charset=UTF-8");
						verifyInfo = merinfoService.validateIdInfo(operatorAuth.getUserName(), operatorAuth.getCardNo(), "1");
						response.getWriter().print(verifyInfo);
						if(verifyInfo){
							updateSqlOp
							.append(" update t_operators t")
							.append(" set t.real_name = ?,")
							.append(" t.card_type=?,")
							.append(" t.card_no=?,")
							.append(" t.sex=?,");
							objList.add(operatorAuth.getUserName());
							objList.add(operatorAuth.getCardType());
							objList.add(operatorAuth.getCardNo());
							String sexStr = "";
							if (operatorAuth.getCardNo().length() == 15 || operatorAuth.getCardNo().length() == 18)
							{
								String lastValue = operatorAuth.getCardNo().substring(operatorAuth.getCardNo().length() - 2, operatorAuth.getCardNo().length()-1);
								sexStr = String.valueOf(Integer.parseInt(lastValue) % 2);
								objList.add(sexStr);
							}else{
								objList.add(sexStr);
							}
							operatorAuth.setUpdateAt(new Date());
							operatorAuth.setUpdateBy(op.getAccountNo());
							updateSqlOp.append(" t.status='05'");
							operatorAuth.setStatus(OperatorAuth.STATUS_TWO);
							sb.append("您的实名认证已经审核通过,您的账号：")
							.append(operatorAuth.getAccountNo());
						}else{
							status="02";
							resultDetail="姓名和身份证号不匹配，请重新认证";
							operatorAuth.setUpdateAt(new Date());
							operatorAuth.setUpdateBy(op.getAccountNo());
							updateSqlOp
							.append(" update t_operators t")
							.append(" set t.status='01' ");
							operatorAuth.setStatus(OperatorAuth.STATUS_THREE);
							sb.append("您的实名认证因姓名和身份证号不匹配被驳回，请重新认证,您的账号：")
							.append(operatorAuth.getAccountNo());
						}
					}else{
						status="02";
						resultDetail="身份证号码已经被使用2次，无法重新使用";
						operatorAuth.setUpdateAt(new Date());
						operatorAuth.setUpdateBy(op.getAccountNo());
						updateSqlOp
						.append(" update t_operators t")
						.append(" set t.status='01' ");
						operatorAuth.setStatus(OperatorAuth.STATUS_THREE);
						sb.append("您的身份证号码已经被使用2次，无法重新使用，请重新认证,您的账号：")
						.append(operatorAuth.getAccountNo());
					}
				}else if(AuditingResultCodeType.REFUSE.getCode().equals(status)){
					status="02";
					operatorAuth.setUpdateAt(new Date());
					operatorAuth.setUpdateBy(op.getAccountNo());
					updateSqlOp
					.append(" update t_operators t")
					.append(" set t.status='01' ");
					operatorAuth.setStatus(OperatorAuth.STATUS_THREE);
					sb.append("您的实名认证被驳回，驳回原因："+resultDetail+"请重新认证,您的账号：")
					.append(operatorAuth.getAccountNo());
				}else{
					status="03";
					operatorAuth.setUpdateAt(new Date());
					operatorAuth.setUpdateBy(op.getAccountNo());
					updateSqlOp.append(" update t_operators t").append(" set t.status='06' "); //审核限制
					operatorAuth.setStatus("4"); //审核限制
					operatorAuth.setExt5("0"); //限制状态 0限制 1解限
					//sb.append("您的实名认证被限制，限制原因："+resultDetail+"请联系代理商,您的账号：").append(operatorAuth.getAccountNo());
					sb.append("您的账号："+operatorAuth.getAccountNo()+"实名认证失败，该账号被限制，请联系您的代理商咨询。");
				}
				objList.add(operatorAuth.getAccountNo());
				updateSqlOp.append(" where t.account_no=?");
				operatorReceive.setStatus(OperatorReceive.STATUS_TWO);
				
				//添加审核信息
				AuditingItem  audit= new AuditingItem();
				audit.setAudit_code(AuditingType.OPERATOR_AUTH_AUTH.getCode());//获取审核编码
				audit.setAudit_name(AuditingType.OPERATOR_AUTH_AUTH.getName());//获取审核名称
				audit.setObj_Audited(operatorReceive.getAccountNo());//审核对象
				audit.setOperators(op.getAccountNo());//操作员账号
				audit.setResult_code(status);
				audit.setResult_detail(resultDetail);
				baseDao.editSave(audit);
				
				//添加短信信息
				logger.info("保存发送短信内容："+sb.toString());
				MessageSend ms = new MessageSend();
				ms.setPhoneNumber(operatorAuth.getAccountNo());
				ms.setMesContent(sb.toString());
				ms.setSendFlag("0");
				ms.setDtCreate(new Date());
				ms.setTimes(0);
				baseDao.editSave(ms);
				
				//添加权限
				/*List<String> list = new ArrayList<String>();
				list.add(ModuleCode.C_M_02_02.getCode());
				list.add(ModuleCode.C_M_04_01.getCode());
				list.add(ModuleCode.C_M_04_02.getCode());
				list.add(ModuleCode.C_M_04_03.getCode());
				list.add(ModuleCode.C_M_04_10.getCode());
				list.add(ModuleCode.C_M_04_11.getCode());
				list.add(ModuleCode.C_M_07_02.getCode());
				list.add(ModuleCode.C_M_07_03.getCode());
				list.add(ModuleCode.C_M_07_04.getCode());
				list.add(ModuleCode.C_M_07_06.getCode());
				
				if(null != list && list.size()>0 ){
					for (int i = 0; i < list.size(); i++) {
						MerchantModuleRight module=new MerchantModuleRight();				
						module.setModuleCode(list.get(i));
						module.setMerchantNo(operatorAuth.getAccountNo());
						module.setOperators(op.getAccountNo());
						baseDao.editSave(module);
						baseDao.addSyslog(SysLogType.POWERINFO_ADD.getCode(), SysLogType.POWERINFO_ADD.getName(), op.getAccountNo(), "商服宝会员"+operatorAuth.getAccountNo()+"添加【"+list.get(i)+"】权限成功!");
					}
				}*/
				
				baseDao.edit(operatorAuth);
				baseDao.edit(operatorReceive);
				sqlBaseDao.deleteBySql(updateSqlOp.toString(), objList);
		}catch(Exception e){
			logger.error(e.getMessage(),e);
			throw new ServiceException(e.getMessage(),e);
		}
		return status;
	}

	@Override
	public OperatorAuth queryOperatorAuthById(Operators op, Long receiveId,Long detailId)
			throws Exception {
		OperatorAuth operatorAuth = new OperatorAuth();
		OperatorReceive operatorReceive = new OperatorReceive();
		try{
			String sql = "";
			if(receiveId!=null&&receiveId>0){
				sql = "select a.operators,to_char(a.dt_create,'YYYY-MM-DD HH24:mi:ss'),a.result_detail from apsmgm.t_auditing_item a where a.obj_audited =(select b.account_no from apsmgm.t_dypay_operators_receive b where b.id=?) and a.audit_code='7001' and a.result_code='02' order by a.dt_create desc";
				Object[] parmas =  new Object[1];
				parmas[0] = receiveId;
				List<Object> list = sqlBaseDao.queryAll(sql, parmas);
				operatorReceive = (OperatorReceive)baseDao.loadById(receiveId, OperatorReceive.class);
				operatorAuth = (OperatorAuth)baseDao.loadById(operatorReceive.getOperatorAuthId(), OperatorAuth.class);
				operatorAuth.setReceiveId(receiveId);
				operatorAuth.setAuthReasonList(list);
				String phoneSql = "SELECT T.IN_REASON FROM APSTFR.TBL_POS_BLACK_INF T WHERE T.BLACK_NUM = ? and  T.IN_FLAG=1";
				Object[] parmas1 =  new Object[1];
				parmas1[0] = operatorAuth.getAccountNo();
				List<Object> list1 = sqlBaseDao.queryAll(phoneSql, parmas1);
				if(list1!=null && list1.size()>0){
					operatorAuth.setPhoneReason(list1.get(0).toString());
				}
				String idCardSql = "SELECT T.IN_REASON FROM APSTFR.TBL_POS_BLACK_INF T WHERE T.BLACK_NUM = ? and  T.IN_FLAG=1";
				Object[] parmas2 =  new Object[1];
				parmas2[0] = operatorAuth.getCardNo();
				List<Object> list2 = sqlBaseDao.queryAll(idCardSql, parmas2);
				if(list2!=null && list2.size()>0){
					operatorAuth.setIdCardReason(list2.get(0).toString());
				}
			}else{
				sql = "select a.operators,to_char(a.dt_create,'YYYY-MM-DD HH24:mi:ss'),a.result_detail from apsmgm.t_auditing_item a where a.obj_audited =(select b.account_no from apsmgm.t_dypay_operators_detail b where b.id=?) and a.audit_code='7001' and a.result_code=? order by a.dt_create desc";
				Object[] parmas =  new Object[2];
				parmas[0] = detailId;
				parmas[1] = "02";
				List<Object> list = sqlBaseDao.queryAll(sql, parmas); 
				operatorAuth = (OperatorAuth)baseDao.loadById(detailId, OperatorAuth.class);
				operatorAuth.setReceiveId(receiveId);
				operatorAuth.setAuthReasonList(list); //驳回理由
				parmas[1] = "03";
				List<Object> llist = sqlBaseDao.queryAll(sql, parmas); 
				operatorAuth.setLimitReasonList(llist); //限制理由
				parmas[1] = "01";
				List<Object> passResltList = sqlBaseDao.queryAll(sql, parmas);
				operatorAuth.setAuthPassReasonList(passResltList);
				String phoneSql = "SELECT T.IN_REASON FROM APSTFR.TBL_POS_BLACK_INF T WHERE T.BLACK_NUM = ? and  T.IN_FLAG=1";
				Object[] parmas1 =  new Object[1];
				parmas1[0] = operatorAuth.getAccountNo();
				List<Object> list1 = sqlBaseDao.queryAll(phoneSql, parmas1);
				if(list1!=null && list1.size()>0){
					operatorAuth.setPhoneReason(list1.get(0).toString());
				}
				String idCardSql = "SELECT T.IN_REASON FROM APSTFR.TBL_POS_BLACK_INF T WHERE T.BLACK_NUM = ? and  T.IN_FLAG=1";
				Object[] parmas2 =  new Object[1];
				parmas2[0] = operatorAuth.getCardNo();
				List<Object> list2 = sqlBaseDao.queryAll(idCardSql, parmas2);
				if(list2!=null && list2.size()>0){
					operatorAuth.setIdCardReason(list2.get(0).toString());
				}
				String receiveIdSql = "select t.id from t_dypay_operators_receive t where t.operator_auth_id=?";
				Object[] parmas3 =  new Object[1];
				parmas3[0] = detailId;
				List<Object> list3 = sqlBaseDao.queryAll(receiveIdSql, parmas3);
				if(list3!=null && list3.size()>0){
					operatorAuth.setReceiveId(Long.parseLong(list3.get(0).toString()));
				}
			}
			
		}catch(Exception e){
			logger.error(e.getMessage(),e);
			throw new ServiceException(e.getMessage(),e);
		}
		return operatorAuth;
	}

	@Override
	public String updateDetailForReleLimitInfo(Operators op, Long detailId, OperatorAuth oprtorAuth) throws ServiceException {
		OperatorAuth operatorAuth = new OperatorAuth();
		List<Object> objList = new ArrayList<Object>();
		StringBuffer updateSqlOp = new StringBuffer();
		String returnStr = "0";
		try {
			operatorAuth = (OperatorAuth)baseDao.loadById(detailId, OperatorAuth.class);
			String querySql = "select count(1) from t_operators where card_no=? and status!='02' and ACCOUNT_NO!=? and ROLE_TYPE='17'";
			Object[] params =  new Object[2];
			params[0] = operatorAuth.getCardNo();
			params[1] = operatorAuth.getAccountNo();
			Object obj = sqlBaseDao.findObj(querySql, params);
			int count = Integer.parseInt(obj.toString());
			boolean isBlackListPass = existBlackList(operatorAuth); //云商宝会员在黑名单则解限失败
			if(!isBlackListPass){
				return returnStr;
			}
			if(count<2){
				StringBuffer sb = new StringBuffer();
				//身份证二要素验证
				HttpServletResponse response=ServletActionContext.getResponse();
				response.setContentType("text/json;charset=UTF-8");
				verifyInfo = merinfoService.validateIdInfo(operatorAuth.getUserName(), operatorAuth.getCardNo(), "1");
				response.getWriter().print(verifyInfo);
				if(verifyInfo){
					updateSqlOp
					.append(" update t_operators t")
					.append(" set t.real_name = ?,")
					.append(" t.card_type=?,")
					.append(" t.card_no=?,")
					.append(" t.sex=?,").append(" t.status='05'");
					objList.add(operatorAuth.getUserName());
					objList.add(operatorAuth.getCardType());
					objList.add(operatorAuth.getCardNo());
					String sexStr = "";
					if (operatorAuth.getCardNo().length() == 15 || operatorAuth.getCardNo().length() == 18)
					{
						String lastValue = operatorAuth.getCardNo().substring(operatorAuth.getCardNo().length() - 2, operatorAuth.getCardNo().length()-1);
						sexStr = String.valueOf(Integer.parseInt(lastValue) % 2);
						objList.add(sexStr);
					}else{
						objList.add(sexStr);
					}
					operatorAuth.setUpdateAt(new Date());
					operatorAuth.setUpdateBy(op.getAccountNo());
					operatorAuth.setExt3(oprtorAuth.getExt3()); //解限备注
					operatorAuth.setExt4(oprtorAuth.getExt4()); //解限图片凭证
					operatorAuth.setExt5("1"); //解限状态
					operatorAuth.setStatus(OperatorAuth.STATUS_TWO);
					sb.append("您的实名认证已经审核通过,您的账号：")
					.append(operatorAuth.getAccountNo());
					objList.add(operatorAuth.getAccountNo());
					updateSqlOp.append(" where t.account_no=?");
					
					//添加审核信息
					AuditingItem  audit= new AuditingItem();
					audit.setAudit_code(AuditingType.OPERATOR_AUTH_AUTH.getCode());//获取审核编码
					audit.setAudit_name(AuditingType.OPERATOR_AUTH_AUTH.getName());//获取审核名称
					audit.setObj_Audited(operatorAuth.getAccountNo());//审核对象
					audit.setOperators(op.getAccountNo());//操作员账号
					audit.setResult_code("04");
					audit.setResult_detail(oprtorAuth.getExt3()); //解限备注
					baseDao.editSave(audit);
					//添加短信信息
					logger.info("保存发送短信内容："+sb.toString());
					MessageSend ms = new MessageSend();
					ms.setPhoneNumber(operatorAuth.getAccountNo());
					ms.setMesContent(sb.toString());
					ms.setSendFlag("0");
					ms.setDtCreate(new Date());
					ms.setTimes(0);
					baseDao.editSave(ms);
					baseDao.edit(operatorAuth);
					sqlBaseDao.deleteBySql(updateSqlOp.toString(), objList);
					returnStr = "1";
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			throw new ServiceException(e.getMessage(),e);
		}
		return returnStr;
	}

	@Override
	public boolean existBlackList(OperatorAuth operatorAuth) throws ServiceException {
		boolean isPass = true;
		try {
			String querySql = "select * from APSTFR.TBL_POS_BLACK_INF t where t.black_num in (?,?) and t.in_flag = 1 ";
			Object[] params = new Object[2];
			params[0] = operatorAuth.getCardNo();
			params[1] = operatorAuth.getAccountNo();
			List<Object> list = sqlBaseDao.queryAll(querySql, params);
			if(list != null && list.size() > 0){
				isPass = false;
			}
		} catch (DaoException e) {
			logger.error(e.getMessage(),e);
			throw new ServiceException(e.getMessage(),e);
		}
		return isPass;
	}

	@Override
	public void updateIdCardDate(Operators op,OperatorAuth operatorAuth)
			throws ServiceException {
		try {
			baseDao.editUpdate(operatorAuth);
			baseDao.addSyslog(SysLogType.YSB_IDCARD_DATE.getCode(), SysLogType.YSB_IDCARD_DATE.getName(), op.getAccountNo(), "操作员【"+op.getAccountNo()+"】修改【"+operatorAuth.getId()+"】【"+operatorAuth.getAccountNo()+"】身份证有限期成功");
		} catch (DaoException e) {
			e.printStackTrace();
		}
	}

	@Override
	public List<String> allotOperRece(Operators op, String accountIdList,
			Operators allotOp) throws ServiceException {
		String updateSql = "update t_dypay_operators_detail t set t.status='3' where t.id=?";
		List<String> receiveList = new ArrayList<String>();
		try{
			String[] accountNoArray = accountIdList.split(",");
			for(int i = 0;i<accountNoArray.length;i++){
				OperatorAuth operatorAuth = (OperatorAuth) baseDao.loadById(Long.parseLong(accountNoArray[i]), OperatorAuth.class);
				if(operatorAuth.getStatus().equals("0")){
					OperatorReceive operatorReceive = new OperatorReceive();
					operatorReceive.setAccountNo(operatorAuth.getAccountNo());
					operatorReceive.setOperatorAuthId(Long.parseLong(accountNoArray[i]));
					operatorReceive.setOpAccountNo(allotOp.getAccountNo());
					operatorReceive.setOpAccountName(allotOp.getRealName());
					operatorReceive.setOpId(allotOp.getId());
					operatorReceive.setCreateAt(new Date());
					operatorReceive.setCreateBy(op.getAccountNo());
					operatorReceive.setStatus(OperatorReceive.STATUS_ONE);
					baseDao.editSave(operatorReceive);
					List<Object> objParmas = new ArrayList<Object>();
					objParmas.add(accountNoArray[i]);
					sqlBaseDao.deleteBySql(updateSql, objParmas);
					baseDao.addSyslog(SysLogType.YSB_ALLOT.getCode(), SysLogType.YSB_ALLOT.getName(), op.getAccountNo(), "操作员【"+op.getAccountNo()+"】将【"+operatorAuth.getId()+"】【"+operatorAuth.getAccountNo()+"】分配给【"+allotOp.getAccountNo()+"】成功");
				}else{
					receiveList.add(accountNoArray[i]);
				}
			}
		}catch(Exception e){
			logger.error(e.getMessage(),e);
			throw new ServiceException(e.getMessage(),e);
		}
		return receiveList;
	}

	@Override
	public Operators queryByAccountNo(String accountNo) {
		Operators operators = new Operators();
		try{
			String sql = "select t.id from t_operators t where t.account_no=?";
			Object[] parmas = new Object[1];
			parmas[0] = accountNo;
			Object obj = sqlBaseDao.findObj(sql,parmas);
			if(obj != null){
				operators.setId(Long.parseLong(obj.toString()));
				operators = (Operators) baseDao.loadById(operators.getId(), Operators.class);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		return operators;
	}


}
